home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Alles Voor Internet / Tout Pour Internet
/
alles voor internet.iso
/
MacInternet™
/
Telnet
/
NCSA
/
tn3270 2.3d26 source
/
tn3270
/
api.c
< prev
next >
Wrap
Text File
|
1991-06-12
|
31KB
|
1,401 lines
/*
* tn3270 for the Macintosh Source Code
* Brown University Computing and Information Services
* Version 2.3d21, January 17, 1991
* Copyright (c) 1988, 1989, 1990, 1991 by Brown University and by
* Peter John DiCamillo.
*
* Permission is granted to any individual or institution to use, copy,
* or redistribute the binary version of this software and its
* documentation provided this notice and the copyright notices are
* retained. Permission is granted to any individual or non-profit
* institution to use, copy, modify, or redistribute the source files
* of this software provided this notice and the copyright notices are
* retained. This software may not be distributed for profit, either
* in original form or in derivative works, nor can the source be
* distributed to other than an individual or a non-profit institution.
* Any individual or group interested in seeing and/or using these
* source files but who are prevented from doing so by the above
* constraints should contact Don Wolfe, Assistant Vice-President for
* Computer Systems at Brown University, (401) 863-7250, for possible
* software licensing of the source developed at Brown.
*
* Brown University and Peter John DiCamillo make no representations
* about the suitability of this software for any purpose.
*
* BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
* EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
* INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#define __SEG__ api
#include "maclib.h"
#include "termdef.h"
#include "globals.h"
#include "telnet.h"
#include "sppc.h"
Handle rcvMessage, sndMessage; /* handles to message buffers */
short fromrefnum; /* data for last received message */
unsigned short msgLength;
unsigned long msgId, replyId;
unsigned char sppc_sessname[8] = "GFTM1-1";
unsigned char ppcsessname[] = "\ptn3270 #1 session 1";
char apimsgkind; /* 0 = PPC, 1 = SPPC */
static unsigned long apimsgid = 0;
long ppcsref; /* used by PPC instead of fromrefnum */
PPCParamBlockPtr newparamblock();
clientinfo * newclientrec();
datainfo * newdatablock();
OSErr apisend();
extern char pend_conn;
extern unsigned char tcphostname[];
extern char servermode; /* server mode active */
extern char hisopts[];
extern short maxoff;
extern char serverflags;
apiregister(char session) /* register our API */
{
sppcregister(session); /* SPPC driver */
if (ppcavail) ppcregister(session); /* PPC Toolbox */
}
sppcregister(char session)
{
static unsigned char smgrname[] = "GFTM1";
short i;
OSErr rc;
if (session == 0) { /* session manager registration */
smgrname[4] = '1';
sppc_sessname[4] = '1';
for (i=0; i < 8; i++) {
rc = SPPCRegister(smgrname, &smgrrefnum);
if (rc == noErr) {
smgr_sppc = 1;
break;
}
else {
smgrname[4]++;
sppc_sessname[4]++;
}
}
if (smgr_sppc) {
if (rcvMessage == 0) rcvMessage = NewHandle((Size)128);
if (sndMessage == 0) sndMessage = NewHandle((Size)128);
if ((rcvMessage == 0) || (sndMessage == 0)) {
apideregister(0);
stoperr(apisalrt);
}
}
else if (rc == dupFNErr) {
stoperr(apinalrt); /* tell user about name problem */
}
}
else if (smgr_sppc) { /* session registration */
sppc_sessname[6] = '1';
for (i=0; i < 8; i++) {
rc = SPPCRegister(sppc_sessname, &sessrefnum);
if (rc == noErr) {
sess_sppc = 1;
break;
}
else {
sppc_sessname[6]++;
}
}
if (!sess_sppc) {
sessrefnum = 0;
stoperr(apinalrt); /* tell user about name problem */
}
}
}
ppcregister(char session)
{
static unsigned char smgrname[] = "\ptn3270 #1";
short i;
OSErr rc;
PPCOpenPBRec openpb;
PPCPortRec pr;
PPCParamBlockPtr ipb;
pascal void (*compproc)();
pascal void smgrinformproc();
pascal void sessinformproc();
if (session == 0) { /* session manager registration */
smgrname[9] = '1';
ppcsessname[9] = '1';
for (i=0; i < 8; i++) {
memset(&pr, 0, sizeof(PPCPortRec));
memcpy(pr.name, smgrname, 10);
pr.portKindSelector = ppcByString;
memcpy(pr.u.portTypeStr, "\ptn3270 Session Manager", 23);
memset(&openpb, 0, sizeof(PPCOpenPBRec));
openpb.serviceType = ppcServiceRealTime;
openpb.portName = ≺
openpb.locationName = 0;
openpb.networkVisible = true;
rc = ppcsync(PPCOpen, &openpb);
if (rc == noErr) {
smgrppc = 1;
smgrpref = openpb.portRefNum;
break;
}
else {
smgrname[9]++;
ppcsessname[9]++;
}
}
if (smgrppc) {
if (rcvMessage == 0) rcvMessage = NewHandle((Size)128);
if (sndMessage == 0) sndMessage = NewHandle((Size)128);
/* issue Inform for our new port */
ipb = newparamblock();
if ((ipb == 0) || (rcvMessage == 0) || (sndMessage == 0)) {
stoperr(ppcopenalrt);
ppcderegister(0);
return;
}
memset(ipb, 0, sizeof(PPCParamBlockRec));
compproc = smgrinformproc;
ipb->informParam.ioCompletion = (PPCCompProcPtr)compproc;
ipb->informParam.portRefNum = smgrpref;
ipb->informParam.autoAccept = false;
rc = ppcasync(PPCInform, ipb);
if (rc != noErr) {
stoperr(ppcopenalrt);
ppcderegister(0);
}
}
else if (rc == -910) {
stoperr(ppcnamealrt); /* tell user about name problem */
}
else {
stoperr(ppcopenalrt); /* other problem */
}
}
else if (smgrppc) { /* session registration */
ppcsessname[19] = '1';
for (i=0; i < 8; i++) {
memset(&pr, 0, sizeof(PPCPortRec));
memcpy(pr.name, ppcsessname, 20);
pr.portKindSelector = ppcByString;
memcpy(pr.u.portTypeStr, "\ptn3270 Session", 15);
memset(&openpb, 0, sizeof(PPCOpenPBRec));
openpb.serviceType = ppcServiceRealTime;
openpb.portName = ≺
openpb.locationName = 0;
openpb.networkVisible = true;
rc = ppcsync(PPCOpen, &openpb);
if (rc == noErr) {
sessppc = 1;
sesspref = openpb.portRefNum;
break;
}
else {
ppcsessname[19]++;
}
}
if (sessppc) {
/* issue Inform for our new port */
ipb = newparamblock();
if (ipb == 0) {
stoperr(ppcnamealrt);
ppcderegister(1);
return;
}
memset(ipb, 0, sizeof(PPCParamBlockRec));
compproc = sessinformproc;
ipb->informParam.ioCompletion = (PPCCompProcPtr)compproc;
ipb->informParam.portRefNum = sesspref;
ipb->informParam.autoAccept = false;
rc = ppcasync(PPCInform, ipb);
if (rc != noErr) {
stoperr(ppcnamealrt);
ppcderegister(1);
}
}
else {
sesspref = 0;
stoperr(ppcnamealrt); /* tell user about name problem */
}
}
}
pascal void smgrinformproc(pb)
PPCParamBlockPtr pb;
{
OSErr rc;
pascal void (*compproc)();
pascal void smgraccproc();
pascal void disposproc();
clientinfo * cip;
PPCParamBlockPtr ipb;
if (pb->informParam.ioResult != noErr) {
disposparamblock(pb);
return;
}
cip = newclientrec();
if (cip == 0) {
compproc = disposproc;
pb->rejectParam.ioCompletion = compproc;
rc = ppcasync(PPCReject, pb);
}
else {
cip->sessrefnum = pb->informParam.sessRefNum;
cip->userdata = pb->informParam.userData;
cip->servicetype = pb->informParam.serviceType;
cip->reqtype = pb->informParam.requestType;
cip->mykind = 0; /* session manager */
compproc = smgraccproc;
pb->acceptParam.ioCompletion = compproc;
rc = ppcasync(PPCAccept, pb);
}
ipb = newparamblock();
if (ipb == 0) {
return;
}
memset(ipb, 0, sizeof(PPCParamBlockRec));
compproc = smgrinformproc;
ipb->informParam.ioCompletion = (PPCCompProcPtr)compproc;
ipb->informParam.portRefNum = smgrpref;
ipb->informParam.autoAccept = false;
rc = ppcasync(PPCInform, ipb);
}
pascal void sessinformproc(pb)
PPCParamBlockPtr pb;
{
OSErr rc;
pascal void (*compproc)();
pascal void sessaccproc();
pascal void disposproc();
clientinfo * cip;
PPCParamBlockPtr ipb;
if (pb->informParam.ioResult != noErr) {
disposparamblock(pb);
return;
}
cip = newclientrec();
if (cip == 0) {
compproc = disposproc;
pb->rejectParam.ioCompletion = compproc;
rc = ppcasync(PPCReject, pb);
}
else {
cip->sessrefnum = pb->informParam.sessRefNum;
cip->userdata = pb->informParam.userData;
cip->servicetype = pb->informParam.serviceType;
cip->reqtype = pb->informParam.requestType;
cip->mykind = 1; /* session */
compproc = sessaccproc;
pb->acceptParam.ioCompletion = compproc;
rc = ppcasync(PPCAccept, pb);
}
ipb = newparamblock();
if (ipb == 0) {
return;
}
memset(ipb, 0, sizeof(PPCParamBlockRec));
compproc = sessinformproc;
ipb->informParam.ioCompletion = (PPCCompProcPtr)compproc;
ipb->informParam.portRefNum = sesspref;
ipb->informParam.autoAccept = false;
rc = ppcasync(PPCInform, ipb);
}
pascal void smgraccproc(pb)
PPCParamBlockPtr pb;
{
datainfo *dip;
OSErr rc;
pascal void (*compproc)();
pascal void disposproc();
pascal void smgrreadproc();
if (pb->acceptParam.ioResult != noErr) {
deletesession(pb->acceptParam.sessRefNum);
disposparamblock(pb);
return;
}
dip = newdatablock();
if (dip == 0) {
compproc = disposproc;
pb->endParam.ioCompletion = compproc;
rc = ppcasync(PPCEnd, pb);
deletesession(pb->acceptParam.sessRefNum);
return;
}
memset(dip, 0, sizeof(datainfo));
compproc = smgrreadproc;
pb->readParam.ioCompletion = compproc;
pb->readParam.bufferLength = 128;
pb->readParam.bufferPtr = dip->msg;
rc = ppcasync(PPCRead, pb);
}
pascal void sessaccproc(pb)
PPCParamBlockPtr pb;
{
datainfo *dip;
OSErr rc;
pascal void (*compproc)();
pascal void disposproc();
pascal void sessreadproc();
if (pb->acceptParam.ioResult != noErr) {
deletesession(pb->acceptParam.sessRefNum);
disposparamblock(pb);
return;
}
dip = newdatablock();
if (dip == 0) {
compproc = disposproc;
pb->endParam.ioCompletion = compproc;
rc = ppcasync(PPCEnd, pb);
deletesession(pb->acceptParam.sessRefNum);
return;
}
memset(dip, 0, sizeof(datainfo));
compproc = sessreadproc;
pb->readParam.ioCompletion = compproc;
pb->readParam.bufferLength = 128;
pb->readParam.bufferPtr = dip->msg;
rc = ppcasync(PPCRead, pb);
}
pascal void disposproc(pb)
PPCParamBlockPtr pb;
{
disposparamblock(pb);
}
pascal void smgrreadproc(pb)
PPCParamBlockPtr pb;
{
datainfo *dip;
OSErr rc;
pascal void (*compproc)();
pascal void disposproc();
unsigned char *s;
if (pb->readParam.ioResult != noErr) {
deletesession(pb->acceptParam.sessRefNum);
disposparamblock(pb);
return;
}
s = (unsigned char *)pb->readParam.bufferPtr;
s -= 24;
dip = (datainfo *)s;
dip->length = pb->readParam.actualLength;
dip->userdata = pb->readParam.userData;
dip->creator = pb->readParam.blockCreator;
dip->type = pb->readParam.blockType;
dip->sessrefnum = pb->readParam.sessRefNum;
dip->more = pb->readParam.more;
dip->incoming = 1;
dip->mykind = 0;
dip->spare = 0;
dip = newdatablock();
if (dip == 0) {
compproc = disposproc;
pb->endParam.ioCompletion = compproc;
rc = ppcasync(PPCEnd, pb);
deletesession(pb->acceptParam.sessRefNum);
return;
}
memset(dip, 0, sizeof(datainfo));
compproc = smgrreadproc;
pb->readParam.ioCompletion = compproc;
pb->readParam.bufferLength = 128;
pb->readParam.bufferPtr = dip->msg;
rc = ppcasync(PPCRead, pb);
}
pascal void sessreadproc(pb)
PPCParamBlockPtr pb;
{
datainfo *dip;
OSErr rc;
pascal void (*compproc)();
pascal void disposproc();
unsigned char *s;
if (pb->readParam.ioResult != noErr) {
deletesession(pb->acceptParam.sessRefNum);
disposparamblock(pb);
return;
}
s = (unsigned char *)pb->readParam.bufferPtr;
s -= 24;
dip = (datainfo *)s;
dip->length = pb->readParam.actualLength;
dip->userdata = pb->readParam.userData;
dip->creator = pb->readParam.blockCreator;
dip->type = pb->readParam.blockType;
dip->sessrefnum = pb->readParam.sessRefNum;
dip->more = pb->readParam.more;
dip->incoming = 1;
dip->mykind = 1;
dip->spare = 0;
dip = newdatablock();
if (dip == 0) {
compproc = disposproc;
pb->endParam.ioCompletion = compproc;
rc = ppcasync(PPCEnd, pb);
deletesession(pb->acceptParam.sessRefNum);
return;
}
memset(dip, 0, sizeof(datainfo));
compproc = sessreadproc;
pb->readParam.ioCompletion = compproc;
pb->readParam.bufferLength = 128;
pb->readParam.bufferPtr = dip->msg;
rc = ppcasync(PPCRead, pb);
}
deletesession(refnum)
long refnum;
{
clientrec *cp;
cp = (clientrec *)clientqueue.first;
while (cp != 0) {
if (cp->header.inuse) {
if (cp->client.sessrefnum == refnum) {
disposclientrec(&(cp->client));
return;
}
}
cp = (clientrec *)cp->header.next;
}
}
apideregister(char session) /* cancel API registration */
{
sppcderegister(session); /* SPPC driver */
ppcderegister(session); /* PPC Toolbox */
apiwritenotify = 0;
}
sppcderegister(char session)
{
/* deregister session, if any */
if (sess_sppc) {
SPPCDeRegister(sessrefnum);
sess_sppc = 0;
}
/* return if just session wanted */
if (session) return;
/* deregister session manager */
if (smgr_sppc) {
SPPCDeRegister(smgrrefnum);
smgr_sppc = 0;
}
}
ppcderegister(char session)
{
PPCClosePBRec closepb;
OSErr rc;
/* deregister session, if any */
if (sessppc) {
memset(&closepb, 0, sizeof(PPCClosePBRec));
closepb.portRefNum = sesspref;
rc = ppcsync(PPCClose, &closepb);
sessppc = 0;
}
/* return if just session wanted */
if (session) return;
/* deregister session manager */
if (smgrppc) {
memset(&closepb, 0, sizeof(PPCClosePBRec));
closepb.portRefNum = smgrpref;
rc = ppcsync(PPCClose, &closepb);
smgrppc = 0;
}
}
apinewmsg()
{
OSErr rc;
datarec *dp;
if (smgr_sppc) {
apimsgkind = 1;
rc = SPPCGet(smgrrefnum, &fromrefnum, 0, rcvMessage, &msgLength,
&msgId, &replyId);
if (rc == noErr) smgrmsg();
if (sess_sppc) {
rc = SPPCGet(sessrefnum, &fromrefnum, 0, rcvMessage, &msgLength,
&msgId, &replyId);
if (rc == noErr) sessmsg();
}
}
if (ppcavail) {
apimsgkind = 0;
dp = (datarec *)dataqueue.first;
while (dp != 0) {
if (dp->header.inuse) {
if (dp->data.incoming) {
ppcsref = dp->data.sessrefnum;
memcpy(*rcvMessage, dp->data.msg, dp->data.length);
msgLength = dp->data.length;
msgId = dp->data.userdata;
replyId = dp->data.creator;
if (dp->data.mykind == 0) {
smgrmsg();
}
else {
sessmsg();
}
disposdatarec(&(dp->data));
}
}
dp = (datarec *)dp->header.next;
}
}
}
smgrmsg()
{
short **msgh;
msgh = (short **)rcvMessage;
if (msgLength < 2) {
senderr(smgrrefnum, badRequestLength);
return;
}
switch (**msgh) {
case GetIdRequestType:
if (msgLength != sizeof(GetIdRequest)) {
senderr(smgrrefnum, badRequestLength);
return;
}
sendid();
break;
case GetCapRequestType:
if (msgLength != sizeof(GetCapRequest)) {
senderr(smgrrefnum, badRequestLength);
return;
}
sendcap();
break;
case GetVersRequestType:
if (msgLength != sizeof(GetVersRequest)) {
senderr(smgrrefnum, badRequestLength);
return;
}
sendvers();
break;
case OpenRequestType:
if (msgLength != sizeof(OpenRequest)) {
senderr(smgrrefnum, badRequestLength);
return;
}
apiopensess();
break;
case GetConnStatusType:
if (msgLength != sizeof(GetConnStatus)) {
senderr(smgrrefnum, badRequestLength);
return;
}
sendconnstat();
break;
default:
senderr(smgrrefnum, badMessageType);
break;
}
}
senderr(myref, code)
short myref, code;
{
ErrorResponse er;
OSErr rc;
long respid;
er.msgtype = ErrorResponseType;
er.code = code;
memcpy(*sndMessage, &er, sizeof(ErrorResponse));
rc = apisend(myref, fromrefnum, msgId, sndMessage, sizeof(ErrorResponse),
&respid);
}
sendcap()
{
GetCapResponse gcr;
OSErr rc;
long respid;
gcr.msgtype = GetCapResponseType;
getsesscount(&gcr.pendsessions, &gcr.currsessions);
gcr.maxsessions = 1;
gcr.numbformats = 1;
gcr.sizeinfo[0].ptsize = 9;
gcr.sizeinfo[0].rows = rowmax9;
gcr.sizeinfo[0].cols = colmax9;
if ((rowmax12 >= 24) && (colmax12 >= 80)) {
gcr.numbformats = 2;
gcr.sizeinfo[1].ptsize = 12;
gcr.sizeinfo[1].rows = rowmax12;
gcr.sizeinfo[1].cols = colmax12;
}
memcpy(*sndMessage, &gcr, sizeof(GetCapResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(GetCapResponse), &respid);
}
getsesscount(pend, curr)
short *pend, *curr;
{
if (serflg && connflg) {
*pend = 0;
*curr = 0;
}
else if (logon || (pend_conn == 3)) {
if (serflg && apiopenpend) {
*pend = 1;
*curr = 0;
}
else {
*pend = 0;
*curr = 1;
}
}
else if (pend_conn > 0) {
*pend = 1;
*curr = 0;
}
else {
*pend = 0;
*curr = 0;
}
}
sendvers()
{
GetVersResponse gvr;
OSErr rc;
long respid;
Handle version;
Size vsize;
memset(&gvr, 0, sizeof(GetVersResponse));
gvr.msgtype = GetVersResponseType;
version = GetResource('vers', 1);
if (version != 0) {
vsize = GetHandleSize(version);
if (vsize > 120) vsize = 120;
memcpy(gvr.versdata, *version, vsize);
}
memcpy(*sndMessage, &gvr, vsize+8);
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage, vsize+8, &respid);
}
sendid()
{
GetIdResponse gir;
OSErr rc;
long respid;
unsigned char apName[256];
short apRefNum;
Handle apParam;
short namelen;
memset(&gir, 0, sizeof(GetIdResponse));
gir.msgtype = GetIdResponseType;
gir.signature = 'GFTM';
GetAppParms(apName, &apRefNum, &apParam);
gir.refnum = apRefNum;
namelen = strlen(apName);
namelen++;
if (namelen > 120) namelen = 120;
memcpy(gir.appname, apName, namelen);
memcpy(*sndMessage, &gir, namelen+12);
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage, namelen+12, &respid);
}
apiopensess()
{
unsigned short len, pend, curr;
char fmtok;
OpenResponse or;
OSErr rc;
long respid;
/* check that a session can be opened now */
getsesscount(&pend, &curr);
if ((pend + curr) > 0) {
memset(&or, 0, sizeof(OpenResponse));
or.msgtype = OpenResponseType;
or.code = openNoSessions;
memcpy(*sndMessage, &or, sizeof(OpenResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(OpenResponse), &respid);
return;
}
/* copy open session request data */
memcpy(&apiopenreq, *rcvMessage, sizeof(OpenRequest));
/* copy host name */
len = strlen(apiopenreq.hostname);
if (len > 255) len = 255;
memcpy(apihostname, apiopenreq.hostname, len+1);
apihostname[len] = 0;
apiopenreq.hostname = apihostname;
/* copy window name */
len = strlen(apiopenreq.windowname);
if (len > 127) len = 127;
memcpy(apiwindowname, apiopenreq.windowname, len+1);
apiwindowname[len] = 0;
apiopenreq.windowname = apiwindowname;
/* copy request message information */
apiopenrefnum = fromrefnum;
apiopenmsgid = msgId;
apiopenkind = apimsgkind;
apiopensref = ppcsref;
/* check the requested screen sizes are valid */
fmtok = 1;
if (apiopenreq.dfltsize.rows != 24) fmtok = 0;
if (apiopenreq.dfltsize.cols != 80) fmtok = 0;
if (apiopenreq.dfltsize.ptsize == 12) {
if (rowmax12 < 24) fmtok = 0;
if (colmax12 < 80) fmtok = 0;
}
else if (apiopenreq.dfltsize.ptsize != 9) fmtok = 0;
if (apiopenreq.altsize.rows < 24) fmtok = 0;
if (apiopenreq.altsize.cols < 80) fmtok = 0;
if (apiopenreq.altsize.ptsize == 9) {
if (rowmax9 < apiopenreq.altsize.rows) fmtok = 0;
if (colmax9 < apiopenreq.altsize.cols) fmtok = 0;
}
else if (apiopenreq.altsize.ptsize == 12) {
if (rowmax12 < apiopenreq.altsize.rows) fmtok = 0;
if (colmax12 < apiopenreq.altsize.cols) fmtok = 0;
}
else fmtok = 0;
if (fmtok == 0) {
apiopenerr(openFormatErr);
return;
}
apiopen = apiopenpend = 1;
if (serflg) serlgin();
else if (tcpflg) tcplgin();
else netlgin();
}
apiopenerr(code)
short code;
{
apiopen = 0;
apiopenresp(code);
}
apiopenresp(code)
short code;
{
OpenResponse or;
OSErr rc;
long respid;
short len;
memset(&or, 0, sizeof(OpenResponse));
or.msgtype = OpenResponseType;
or.code = code;
if ((code == open3270Mode) || (code == openLineMode)) {
if (smgr_sppc) {
or.sppcrefnum = sessrefnum;
if (sppc_sessname != 0) {
len = strlen(sppc_sessname);
if (len > 8) len = 8;
memcpy(or.sppcname, sppc_sessname, len+1);
}
}
if (smgrppc) {
or.ppcportnum = sesspref;
if (ppcsessname != 0) {
p2cstr(ppcsessname);
len = strlen(ppcsessname);
if (len > 20) len = 20;
memcpy(or.ppcname, ppcsessname, len+1);
c2pstr(ppcsessname);
}
}
}
memcpy(*sndMessage, &or, sizeof(OpenResponse));
/* restore message information */
fromrefnum = apiopenrefnum;
msgId = apiopenmsgid;
apimsgkind = apiopenkind;
ppcsref = apiopensref;
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(OpenResponse), &respid);
apiopenpend = 0;
}
sendconnstat()
{
GetConnResponse gcr;
unsigned long openid;
OSErr rc;
long respid;
short len;
short getconnstat();
openid = (*((GetConnStatus **)rcvMessage))->openid;
memset(&gcr, 0, sizeof(GetConnResponse));
gcr.msgtype = GetConnResponseType;
if (apiopen) gcr.openid = apiopenmsgid;
else gcr.openid = 0;
gcr.statuscode = getconnstat(openid);
memcpy(*sndMessage, &gcr, sizeof(GetConnResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(GetConnResponse), &respid);
}
short getconnstat(openid)
unsigned long openid;
{
if (apiopen == 0) return(openBadId);
if (openid != apiopenmsgid) return(openBadId);
if (apiopenpend == 0) {
if (logon) return(open3270Mode);
else return(openLineMode);
}
if (serflg) return(openConnPending);
switch(pend_conn) {
case 1:
return(openResPending);
break;
case 2:
return(openConnPending);
break;
case 3:
return(openNegOptions);
break;
default:
return(noError);
break;
}
}
OSErr apisend(short myRefNum, short toRefNum,
unsigned long replyId, Handle theMessage,
unsigned short msgLength, unsigned long *msgId)
{
PPCParamBlockPtr wbp;
datainfo *dp;
pascal void (*compproc)();
pascal void writeproc();
if (apimsgkind == 1) {
return(SPPCSend(myRefNum, toRefNum, replyId, theMessage,
msgLength, msgId));
}
else {
wbp = newparamblock();
if (wbp == 0) {
return(mFulErr);
}
dp = newdatablock();
if (dp == 0) {
disposparamblock(wbp);
return(mFulErr);
}
memset(wbp, 0, sizeof(PPCParamBlockRec));
compproc = writeproc;
wbp->writeParam.ioCompletion = compproc;
wbp->writeParam.sessRefNum = ppcsref;
wbp->writeParam.bufferLength = msgLength;
wbp->writeParam.bufferPtr = dp->msg;
apimsgid++;
wbp->writeParam.userData = apimsgid;
wbp->writeParam.blockCreator = replyId;
memset(dp, 0, sizeof(datainfo));
memcpy(dp->msg, *theMessage, msgLength);
return(ppcasync(PPCWrite, wbp));
}
}
pascal void writeproc(pb)
PPCParamBlockPtr pb;
{
unsigned char *s;
datainfo * d;
s = (unsigned char *)pb->writeParam.bufferPtr;
s -= 24;
d = (datainfo *)s;
disposdatarec(d);
disposparamblock(pb);
}
sessmsg()
{
short **msgh;
msgh = (short **)rcvMessage;
if (msgLength < 2) {
senderr(sessrefnum, badRequestLength);
return;
}
switch (**msgh) {
case GetCharRequestType:
if (msgLength != sizeof(GetCharRequest)) {
senderr(sessrefnum, badRequestLength);
return;
}
sendchar();
break;
case CloseRequestType:
if (msgLength != sizeof(CloseRequest)) {
senderr(sessrefnum, badRequestLength);
return;
}
sessclose();
break;
case CloseNotifyRequestType:
if (msgLength != sizeof(CloseNotifyRequest)) {
senderr(sessrefnum, badRequestLength);
return;
}
closenotify();
break;
case GetBuffersRequestType:
if (msgLength != sizeof(GetBuffersRequest)) {
senderr(sessrefnum, badRequestLength);
return;
}
getbuffers();
break;
case WriteNotifyRequestType:
if (msgLength != sizeof(WriteNotifyRequest)) {
senderr(sessrefnum, badRequestLength);
return;
}
writenotify();
break;
case SendDataRequestType:
if (msgLength != sizeof(SendDataRequest)) {
senderr(sessrefnum, badRequestLength);
return;
}
senddatareq();
break;
case SendLocalRequestType:
if (msgLength != sizeof(SendLocalRequest)) {
senderr(sessrefnum, badRequestLength);
return;
}
sendlocal();
break;
default:
senderr(sessrefnum, badMessageType);
break;
}
}
sendchar()
{
GetCharResponse gcr;
OSErr rc;
long respid;
unsigned char *dest, *s;
short len, conn;
memset(&gcr, 0, sizeof(GetCharResponse));
gcr.msgtype = GetCharResponseType;
dest = (*((GetCharRequest **)rcvMessage))->hostname;
if (dest != 0) {
if (tcpflg) {
s = tcphostname;
}
else {
s = cshostname;
}
len = strlen(s);
if (len > 255) len = 255;
memcpy(dest, s, len+1);
}
dest = (*((GetCharRequest **)rcvMessage))->windowname;
if (dest != 0) {
if (apiopen) {
s = apiwindowname;
}
else {
s = wtitle;
}
len = strlen(s);
if (len > 127) len = 127;
memcpy(dest, s, len+1);
}
gcr.dfltsize.ptsize = ses_dfltptsize;
gcr.dfltsize.rows = 24;
gcr.dfltsize.cols = 80;
gcr.altsize.ptsize = ses_altptsize;
gcr.altsize.rows = ses_altrows;
gcr.altsize.cols = ses_altcols;
gcr.linemode = (logon == 0);
if (apiopen) {
gcr.hide = apiopenreq.hide;
gcr.nowsf = apiopenreq.nowsf;
gcr.noalert = apiopenreq.noalert;
}
else {
gcr.hide = gcr.noalert = 0;
gcr.nowsf = (cs.ext3270 == 0);
}
memcpy(*sndMessage, &gcr, sizeof(GetCharResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(GetCharResponse), &respid);
}
sessclose()
{
CloseResponse cr;
OSErr rc;
long respid;
memset(&cr, 0, sizeof(CloseResponse));
cr.msgtype = CloseResponseType;
cr.code = noError;
memcpy(*sndMessage, &cr, sizeof(CloseResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(CloseResponse), &respid);
closeresponse(closeAPI);
if (serflg) serlgout(0xe3);
else if (tcpflg) tcplgout();
else netlgout();
}
closenotify()
{
CloseNotifyResponse cnr;
OSErr rc;
long respid;
memset(&cnr, 0, sizeof(CloseNotifyResponse));
cnr.msgtype = CloseNotifyResponseType;
if ((*((CloseNotifyRequest **)rcvMessage))->notifyflag) {
if (apiclosenotify) {
cnr.code = closeNotifyActive;
}
else {
cnr.code = noError;
apiclosenotify = 1;
/* copy request message information */
apicloserefnum = fromrefnum;
apiclosemsgid = msgId;
apiclosekind = apimsgkind;
apiclosesref = ppcsref;
}
}
else {
apiclosenotify = 0;
cnr.code = noError;
}
memcpy(*sndMessage, &cnr, sizeof(CloseNotifyResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(CloseNotifyResponse), &respid);
}
closeresponse(code)
short code;
{
CloseEventResponse cer;
OSErr rc;
long respid;
if (!apiclosenotify) return;
memset(&cer, 0, sizeof(CloseEventResponse));
cer.msgtype = CloseEventResponseType;
cer.code = code;
if (smgr_sppc) {
cer.sppcrefnum = sessrefnum;
}
if (smgrppc) {
cer.ppcportnum = sesspref;
}
memcpy(*sndMessage, &cer, sizeof(CloseEventResponse));
/* restore message information */
fromrefnum = apicloserefnum;
msgId = apiclosemsgid;
apimsgkind = apiclosekind;
ppcsref = apiclosesref;
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(CloseEventResponse), &respid);
apiclosenotify = 0;
}
getbuffers()
{
GetBuffersResponse gbr;
OSErr rc;
long respid;
memset(&gbr, 0, sizeof(GetBuffersResponse));
gbr.msgtype = GetBuffersResponseType;
gbr.databuff = chrbuff;
gbr.attrbuff = atrbuff;
gbr.kblock = &kblock;
gbr.kblcode = &kblcode;
gbr.curadr = &curadr;
memcpy(*sndMessage, &gbr, sizeof(GetBuffersResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(GetBuffersResponse), &respid);
}
writenotify()
{
WriteNotifyResponse wnr;
OSErr rc;
long respid;
memset(&wnr, 0, sizeof(WriteNotifyResponse));
wnr.msgtype = WriteNotifyResponseType;
if ((*((WriteNotifyRequest **)rcvMessage))->notifyflag) {
if (apiwritenotify) {
wnr.code = writeNotifyActive;
}
else {
wnr.code = noError;
apiwritenotify = 1;
/* copy request message information */
apiwriterefnum = fromrefnum;
apiwritemsgid = msgId;
apiwritekind = apimsgkind;
apiwritesref = ppcsref;
}
}
else {
apiwritenotify = 0;
wnr.code = noError;
}
memcpy(*sndMessage, &wnr, sizeof(WriteNotifyResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(WriteNotifyResponse), &respid);
}
writeresponse(ccwop)
unsigned char ccwop;
{
WriteEventResponse wer;
OSErr rc;
long respid;
if (!apiwritenotify) return;
memset(&wer, 0, sizeof(WriteEventResponse));
wer.msgtype = WriteEventResponseType;
wer.ccwop = ccwop;
if (smgr_sppc) {
wer.sppcrefnum = sessrefnum;
}
if (smgrppc) {
wer.ppcportnum = sesspref;
}
memcpy(*sndMessage, &wer, sizeof(WriteEventResponse));
/* restore message information */
fromrefnum = apiwriterefnum;
msgId = apiwritemsgid;
apimsgkind = apiwritekind;
ppcsref = apiwritesref;
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(WriteEventResponse), &respid);
}
senddatareq()
{
SendDataResponse sdr;
OSErr rc;
long respid;
unsigned short caddr;
short length;
unsigned char *s;
unsigned char aidcode;
short i;
char geflag;
memset(&sdr, 0, sizeof(SendDataResponse));
sdr.msgtype = SendDataResponseType;
length = (*((SendDataRequest **)rcvMessage))->length;
s = (*((SendDataRequest **)rcvMessage))->data;
if (connflg && serflg) { /* serial connection mode */
if (length > 0) {
for (i=0; i < length; i++) {
apisendser(s[i]);
sdr.count++;
}
}
}
else if (tcpflg && (pend_conn == 3)) {
if (length > 0) { /* 3270 line mode */
if (servermode) {
putsrv(s, length, 1);
}
else {
if (!hisopts[TELOPT_ECHO]) {
putscr(s, length, 0);
}
tcpwrite(s, length);
}
sdr.count = length;
}
}
else { /* 3270 session */
caddr = (*((SendDataRequest **)rcvMessage))->curadr;
aidcode = (*((SendDataRequest **)rcvMessage))->aidcode;
/* check for fatal errors */
if (kblock) {
sdr.code = sendLocked;
}
else if ((caddr != 0xffff) && (caddr > maxoff)) {
sdr.code = sendBadAddress;
}
if (sdr.code == noError) {
/* set cursor address */
if (caddr != 0xffff) {
curadr = caddr;
newcur();
}
/* store data */
if (length > 0) {
geflag = 0;
apikberr = 0;
for (i=0; i < length; i++) {
if (s[i] == 0x08) {
geflag = 1;
}
else {
datakey(s[i], geflag);
geflag = 0;
if (apikberr) {
sdr.code = apikberr;
break;
}
else {
sdr.count++;
}
}
}
}
/* send AID */
if ((aidcode != 0) && (sdr.code == noError)) {
apikberr = 0;
attnkey(aidcode);
sdr.code = apikberr;
}
}
}
sdr.curadr = curadr;
memcpy(*sndMessage, &sdr, sizeof(SendDataResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(SendDataResponse), &respid);
}
apisendser(c)
unsigned char c;
{
if (c == 0x12) {
serverflags = 0x01;
srvswitch();
}
else {
if (servermode) {
putsrv(&c, 1, 1);
}
else {
mout(c);
}
}
}
sendlocal()
{
SendLocalResponse slr;
OSErr rc;
long respid;
unsigned short caddr;
short length;
unsigned char *s;
short i;
memset(&slr, 0, sizeof(SendLocalResponse));
slr.msgtype = SendLocalResponseType;
length = (*((SendLocalRequest **)rcvMessage))->length;
s = (*((SendLocalRequest **)rcvMessage))->data;
if (length > 0) {
/* check for fatal errors */
if (kblock) {
if (s[0] != 13) {
slr.code = sendLocked;
}
}
if (slr.code == noError) {
/* execute operations */
apikberr = 0;
for (i=0; i < length; i++) {
funckey(s[i]);
if (apikberr) {
slr.code = apikberr;
break;
}
else {
slr.count++;
}
}
}
}
slr.curadr = curadr;
memcpy(*sndMessage, &slr, sizeof(SendLocalResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(SendLocalResponse), &respid);
}